home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / DIALOGS / JANUSW / DIALOGWN.PAS < prev    next >
Pascal/Delphi Source File  |  1994-11-14  |  33KB  |  981 lines

  1. Unit DialogWn;
  2. { Unit:      DialogWn
  3.   Version:   1.33
  4.   Purpose:   make a descendant of tWindow named tDialogWindow that behaves like
  5.              a modeless or modal dialog.
  6.   Developer: Peter Sawatzki (ps)
  7.              Buchenhof 3, D58091 Hagen, Germany
  8.  CompuServe: 100031,3002
  9.  
  10.   Date:    Author:
  11.   04/22/92 ps     initial release by ps
  12.   07/25/92 ps/jwp added Scroller support
  13.   08/01/92 ps     added RunModal and modal support
  14.   08/12/92 ps     removed SetClassName and NewClass, fixed bug in MDI support
  15.   08/14/92 ps     fixed Focus problems in MDI, give focus to first ws_TabStop child
  16.   08/30/92 ps     fixed more focus problems in MDI, added SysModal support
  17.   09/27/92 ps     call DefDlgProc to support DropDownBoxes and Multiline edit controls
  18.   10/21/92 ps     some changes for new OWL
  19.   01/28/93 ps     add LoadMenu for automatic menu load
  20.   02/06/93 ps     add support for InitResource, fix BWCC's WM_NCCREATE glitch
  21.   06/10/93 ps     added CanClose method to cancel modal dialogs
  22.   06/15/93 dob    removed CanClose, added WMQueryEndSession
  23.   06/17/93 dob/ps added wmKillFocus and wmNCActivate methods, modified wmSetFocus method
  24.   06/29/93 ps     added tAdvApplication object to resolve focus problems
  25.   07/01/93 ps     added tAdvMdiWindow object to solve MessageBox problem
  26.   07/05/93 ps     added hEditBuffer to save system resources for Edit Ctls
  27.   07/23/93 ps     added wm_EnterIdle sending to RunModal
  28.   08/10/93 ps     fixed ListBox focus problem
  29.   08/28/93 ps     added dm_SetDefId and dm_GetDefId handling
  30.   08/30/93 ps     added calls to DefDialogProc() for proper default PushButton handling
  31.   09/02/93 ps     included tJanusDialogWindow properties in tDialogWindow
  32.   09/11/93 ps     added Ctl3D support
  33.   10/01/93 ps     added use of DynLink to DYNAMICALLY link DLLs
  34.   10/15/93 ps     added focus autofollow
  35.   12/10/93 ps     added BorDlg_Gray support
  36.   01/01/94 ms/ps  fixed Ctl-Tab bug in wmSysCommand, change wmSetFocus
  37.   01/01/94 ps     remove all calls to DefDlgProc, do all DefDlg stuff in tDialogWindow
  38.   01/21/94 ps     fix bug in resource parsing when menuname is an integer atom of form #$xx00
  39.   02/14/94 ps     added support for VBX control
  40.   03/03/94 ps     fix OWL wm_Activate bug
  41.   03/14/94 pl/ps  make MapDialogRect compatible
  42.   08/01/94 ps/sm  added wm_GetFont, better values for XLine/YLine,
  43.                   remove calls to BWCC.DefWndProc, remove wmPaint
  44.  
  45.   Contributing: Jeroen W. Pluimers (jwp)
  46.                 Dan O. Butler (dob) [72134,633]
  47.                 Andy Cook [71331,501]
  48.                 Dean Wyant [75110,3253]
  49.                 Max Stempfhuber (ms) [100140,2034]
  50.                 Per Larsen (pl) [100121,1514]
  51.                 Sebastian Modersohn [100340,1474]
  52.  
  53.   Copyright (c) 1994 Peter Sawatzki. All Rights Reserved.
  54.  
  55. }
  56. {$A+,B-,F-,G+,I-,K+,P-,Q-,R-,S-,T-,V-,X+}
  57. Interface
  58. Uses
  59.   DynLink,
  60.   Vbx,
  61.   WinTypes,
  62.   Win31,
  63. {$IfDef Custom}
  64.   CustomWn,
  65. {$EndIf}
  66. {$IfDef Debug}
  67.   Debug,
  68. {$EndIf}
  69.   Objects,
  70.   oWindows;
  71. Const
  72.   wm_EnterMenuLoop = $0211;   {undocumented}
  73.   MdiS_AllChildStyles = $0001;
  74.  
  75.   {-private message for tDialogWindow}
  76.   wm_TrackFocus = (wm_User+3);
  77.  
  78.   {-style bits for DlgStyle}
  79.   OrgStyle   = $00;
  80.   ForceStd   = $01; {Force BorDlgs to appear as Std dialogs}
  81.   ForceBor   = $02; {Force Std dialogs to appear as BorDlgs}
  82.   EnableCtl3D= $04; {Enable Ctl3D}
  83.   ForceGrayBk= $08; {Force a gray background}
  84.   GrayBorDlg = $10; {gray Borland dialogs}
  85.   DefStyle: Word = OrgStyle Or EnableCtl3D Or ForceGrayBk; {use OrgStyle by default}
  86.   DefCtl3DStyle: LongInt = Ctl3D_All;
  87.   DefFontWeight: Integer = fw_Bold; {standard Windows behaviour}
  88.  
  89. Type
  90.   tChildClass = Record
  91.     wX, wY, wCX, wCY: Integer;
  92.     wID: Word;
  93.     dwStyle: LongInt;
  94.     szClass: Array[0..63] Of Char;
  95.     szTitle: Array[0..131] Of Char;
  96.     CtlDataSize: Byte;
  97.     CtlData: Array[0..255] Of Byte;
  98.   End;
  99.  
  100.   tDialogWindowAttr = Record
  101.     Name: pChar;
  102.     ItemCount: Integer;
  103.     MenuName,
  104.     ClassName,
  105.     FontName: pChar;
  106.     Font: hFont;
  107.     FontWeight: Integer;
  108.     PointSize: Integer;
  109.     DlgItems: Pointer; {only valid ...}
  110.     VbInfo: Pointer;   {... during Create}
  111.     ResW,              {dialogs initial width ...}
  112.     ResH: Integer;     {... and height}
  113.     wUnitsX,
  114.     wUnitsY: Word;
  115.     hEditBuffer: tHandle;
  116.   End;
  117.  
  118. {$IfDef Custom}
  119.   Ancestor = tCustomWindow;
  120. {$Else}
  121.   Ancestor = tWindow;
  122. {$EndIf}
  123.   pDialogWindow = ^tDialogWindow;
  124.   tDialogWindow = Object(Ancestor)
  125.     DialogAttr: tDialogWindowAttr;
  126.     ModalCode: pInteger;
  127.  
  128.     DlgStyle: Word;
  129.     Ctl3DStyle: LongInt;
  130.     DefId: hWnd;
  131.     IsBorDlg: Boolean;
  132.     Constructor Init       (aParent: pWindowsObject; aName: pChar);
  133.     Constructor InitCustom (aParent: pWindowsObject; aName: pChar; aDlgStyle: Word);
  134.     Destructor Done;                                 Virtual;
  135.     Procedure AllocateEditBuffer;                    Virtual;
  136.     Function  Create: Boolean;                       Virtual;
  137.     Procedure Destroy;                               Virtual;
  138.     Procedure SetupWindow;                           Virtual;
  139.     Function  GetClassName: pChar;                   Virtual;
  140.     Procedure GetWindowClass (Var aWndClass: tWndClass); Virtual;
  141.     Procedure GetChildClass (Var aChildClass: tChildClass); Virtual;
  142.     Procedure MangleChildClass (Var aChildClass: tChildClass); Virtual;
  143.     Function  CreateDialogChild ({Bp7.01: Const} Var aChildClass: tChildClass): hWnd; Virtual;
  144.     Function  CreateDialogChildren: Boolean;         Virtual;
  145.     Procedure CreateDialogFont;
  146.     Procedure GetDialogInfo (aPtr: Pointer);
  147.     Procedure StoreDMInfo;
  148.     Procedure UpdateDialog;                          Virtual;
  149.     Procedure MangleClass;                           Virtual;
  150.     Function  RunModal: Integer;                     Virtual;
  151.     Function  IsModal: Boolean;
  152.     Procedure EndDlg (aRetValue: Integer);           Virtual;
  153.     Function  GetItemHandle (DlgItemID: Integer): hWnd;
  154.     Function  SendDlgItemMsg (DlgItemID: Integer; aMsg, wParam: Word; lParam: LongInt): LongInt;
  155.     Procedure Ok (Var Msg: tMessage);                Virtual id_First+id_Ok;
  156.     Procedure Cancel (Var Msg: tMessage);            Virtual id_First+id_Cancel;
  157.     Procedure wmClose (Var Msg: tMessage);           Virtual wm_First+wm_Close;
  158.     Procedure wmQueryEndSession (Var Msg: tMessage); Virtual wm_First+wm_QueryEndSession;
  159.     Procedure wmSize (Var Msg: tMessage);            Virtual wm_First+wm_Size;
  160.     Procedure wmLButtonDown (Var Msg: tMessage);     Virtual wm_First+wm_LButtonDown;
  161.     Procedure wmNcLButtonDown (Var Msg: tMessage);   Virtual wm_First+wm_NcLButtonDown;
  162.     Procedure wmEnterMenuLoop (Var Msg: tMessage);   Virtual wm_First+wm_EnterMenuLoop;
  163.     Procedure wmActivate (Var Msg: tMessage);        Virtual wm_First+wm_Activate;
  164.     Procedure HideComboListBox;
  165.     Procedure wmNextDlgCtl (Var Msg: tMessage);      Virtual wm_First+wm_NextDlgCtl;
  166.     Procedure dmGetDefId (Var Msg: tMessage);        Virtual wm_First+dm_GetDefId;
  167.     Procedure wmGetFont (Var Msg: tMessage);         Virtual wm_First+wm_GetFont;
  168.     Procedure wmTrackFocus (Var Msg: tMessage);      Virtual wm_First+wm_TrackFocus;
  169.     Procedure wmSetFocus (Var Msg: tMessage);        Virtual wm_First+wm_SetFocus;
  170.     Procedure wmCtlColor (Var Msg: tMessage);        Virtual wm_First+wm_CtlColor;
  171.     Procedure wmEraseBkGnd (Var Msg: tMessage);      Virtual wm_First+wm_EraseBkGnd;
  172.     Procedure wmVbxFireEvent (Var Msg: tMessage);    Virtual wm_First+wm_VbxFireEvent;
  173.     Procedure DefaultEventProc (Var Event: tVbxEvent); Virtual;
  174.   End;
  175.  
  176.   pAdvApplication = ^tAdvApplication;
  177.   tAdvApplication = Object(tApplication)
  178.     Function ProcessDlgMsg (Var Message: tMsg): Boolean; Virtual;
  179.     Function ProcessAppMsg (Var Message: tMsg): Boolean; Virtual;
  180.   End;
  181.  
  182.   pAdvMdiWindow = ^tAdvMdiWindow;
  183.   tAdvMdiWindow = Object(tMdiWindow)
  184.     Procedure wmActivate (Var Msg: tMessage); Virtual wm_First+wm_Activate;
  185.   End;
  186.  
  187.   Function ExecDialogWindow (aDialogWindow: pDialogWindow): Integer;
  188.  
  189. Implementation
  190. Uses
  191.   WinProcs,
  192.   Strings;
  193.  
  194. Const
  195.   sztDialogWindow = 'tDialogWindow';
  196.  
  197.   ws_MdiChild   = ws_Child Or ws_ClipSiblings Or ws_SysMenu Or ws_Caption Or
  198.                   ws_ThickFrame Or ws_MinimizeBox Or ws_MaximizeBox Or ws_Visible;
  199.   ws_MdiAllowed = ws_MdiChild Or ws_Minimize Or ws_Maximize Or ws_ClipChildren Or
  200.                   ws_Disabled Or ws_HScroll Or ws_VScroll Or ws_ThickFrame Or $FFFF;
  201.   {dialog window words}
  202.   dwl_MsgResult     = 0;
  203.   dwl_DlgProc       = 4;
  204.   dwl_User          = 8;
  205.   dww_wUnitsX       = 12;
  206.   dww_wUnitsY       = 14;
  207.   dww_hWndFocusSave = 16;
  208.   dww_fEnd          = 18; {DM's flag for end dialog}
  209.   dww_Result        = 22; {default id and dialog result}
  210.   dww_hData         = 24; {handle to edit memory block}
  211.   dww_hUserFont     = 26; {handle to dialog font}
  212.  
  213. Function DlgToClientX (x, Units: Integer): Integer;
  214. {DlgToClientX:= x*Units Div 4}
  215. Inline($59/$58/    {Pop Cx Ax}
  216.        $F7/$E1/    {Mul Cx}
  217.        $D1/$E8/    {Shr Ax,1}
  218.        $D1/$E8);   {Shr Ax,1}
  219.  
  220. Function DlgToClientY (y, Units: Integer): Integer;
  221. {DlgToClientY:= y*Units Div 8}
  222. Inline($59/$58/    {Pop Cx Ax}
  223.        $F7/$E1/    {Mul Cx}
  224.        $D1/$E8/    {Shr Ax,1}
  225.        $D1/$E8/    {Shr Ax,1}
  226.        $D1/$E8);   {Shr Ax,1}
  227.  
  228. Constructor tDialogWindow.Init (aParent: pWindowsObject; aName: pChar);
  229. Begin
  230.   Inherited Init(aParent,sztDialogWindow); {fake title}
  231.   FillChar(DialogAttr,SizeOf(DialogAttr),0);
  232.   ModalCode:= Nil;                         {assume modeless window}
  233.   DlgStyle:= DefStyle;                     {assume default style}
  234.   Ctl3DStyle:= DefCtl3DStyle;
  235.   IsBorDlg:= False;                        {really unknown at this moment}
  236.   DefId:= 0;
  237.   With DialogAttr Do Begin
  238.     hEditBuffer:= 0;                       {no edit buffer allocated yet}
  239.     FontWeight:= DefFontWeight;            {Windows standard dialogs are bold}
  240.     If PtrRec(aName).Seg=0 Then Name:= aName Else Name:= StrNew(aName)
  241.   End
  242. End;
  243.  
  244. Constructor tDialogWindow.InitCustom (aParent: pWindowsObject; aName: pChar; aDlgStyle: Word);
  245. Begin
  246.   tDialogWindow.Init (aParent, aName); {very important to use 'tDialogWindow.' !!!}
  247.   DlgStyle:= aDlgStyle
  248. End;
  249.  
  250. Destructor tDialogWindow.Done;
  251. Begin
  252.   With DialogAttr Do Begin
  253.     If PtrRec(Name).Seg<>0 Then StrDispose(Name);
  254.     If PtrRec(MenuName).Seg<>0 Then StrDispose(MenuName);
  255.     StrDispose(ClassName);
  256.     StrDispose(FontName)
  257.   End;
  258.   Inherited Done
  259. End;
  260.  
  261. Procedure tDialogWindow.AllocateEditBuffer;
  262. {-allocate a local heap for edit controls}
  263. Begin
  264.   DialogAttr.hEditBuffer:= GlobalAlloc(GHnd, 4096)
  265. End;
  266.  
  267. Function tDialogWindow.Create: Boolean;
  268. Var
  269.   aRes, VbRes: tHandle;
  270. Begin
  271.   Create:= False;
  272.   If (Status<>0) Or (DialogAttr.Name=Nil) Then
  273.     Exit;
  274.   aRes:= FindResource(hInstance, DialogAttr.Name, rt_Dialog);
  275.   If aRes<>0 Then
  276.     aRes:= LoadResource(hInstance, aRes);
  277.   If aRes=0 Then
  278.     Status:= em_InvalidWindow
  279.   Else Begin
  280.     If Assigned(ModalCode) Then Begin
  281.       If Assigned(Parent) Then
  282.         EnableWindow(Parent^.hWindow, False); {disable Parent}
  283.       ModalCode^:= 0                          {begin modal state}
  284.     End;
  285.     VbRes:= FindResource(hInstance, DialogAttr.Name, rt_DlgInit);
  286.     If VbRes<>0 Then Begin
  287.       VbRes:= LoadResource(hInstance, VbRes);
  288.       DialogAttr.VbInfo:= LockResource(VbRes)
  289.     End;
  290.     GetDialogInfo(LockResource(aRes));
  291.     If Assigned(DialogAttr.MenuName) Then
  292.       Attr.Menu:= LoadMenu(hInstance, DialogAttr.MenuName);
  293.     CreateDialogFont;
  294.     UpdateDialog;
  295.     MangleClass;
  296.     EnableKBHandler;
  297.     Create:= Inherited Create;
  298.     UnlockResource(aRes);
  299.     FreeResource(aRes);
  300.     If VbRes<>0 Then Begin
  301.       UnlockResource(VbRes);
  302.       FreeResource(VbRes)
  303.     End
  304.   End
  305. End;
  306.  
  307. Procedure tDialogWindow.Destroy;
  308. Begin
  309.   If Assigned(ModalCode) Then Begin
  310.     If Assigned(Parent) Then
  311.       EnableWindow(Parent^.hWindow,True); {enable Parent}
  312.     If ModalCode^=0 Then {terminate modal window if not already terminated}
  313.       ModalCode^:= id_Cancel
  314.   End;
  315.  
  316.   Inherited Destroy;
  317.   With DialogAttr Do Begin
  318.     If Assigned(FontName) Then
  319.       DeleteObject(Font);
  320.     If hEditBuffer<>0 Then
  321.       hEditBuffer:= GlobalFree(hEditBuffer)
  322.   End;
  323. End;
  324.  
  325. Procedure tDialogWindow.SetupWindow;
  326. Begin
  327.   StoreDMInfo;
  328.   SendMessage(hWindow,wm_SetFont,DialogAttr.Font,0);
  329.   If Not CreateDialogChildren Then
  330.     Status:= em_InvalidChild;
  331.   Inherited SetupWindow
  332. End;
  333.  
  334. (*Procedure tDialogWindow.wmPaint(Var Msg: tMessage);
  335. Var
  336.   PaintInfo: tPaintStruct;
  337.   aRect: tRect;
  338. Begin
  339.   PaintInfo.hDC:= GetDC(hWindow); {BeginPaint does not do the job}
  340.   GetClientRect(hWindow, PaintInfo.rcPaint);
  341.   If Assigned(Scroller) Then Scroller^.BeginView(PaintInfo.hDC, PaintInfo);
  342.   Paint(PaintInfo.hDC, PaintInfo);
  343.   If Assigned(Scroller) Then Scroller^.EndView;
  344.   ReleaseDC(hWindow, PaintInfo.hDC);
  345.   DefWndProc(Msg)
  346. End;
  347. *)
  348.  
  349. Function tDialogWindow.GetClassName: pChar;
  350. Begin
  351.   If Assigned(DialogAttr.ClassName) Then
  352.     GetClassName:= DialogAttr.ClassName
  353.   Else
  354.     GetClassName:= wc_Dialog
  355. End;
  356.  
  357. Procedure tDialogWindow.GetWindowClass (Var aWndClass: tWndClass);
  358. Begin
  359.   Inherited GetWindowClass(aWndClass);
  360.   aWndClass.cbWndExtra:= DlgWindowExtra
  361. End;
  362.  
  363. Procedure tDialogWindow.GetChildClass (Var aChildClass: tChildClass);
  364. {-change a childs window class. Standard windows behaviour is simulated here:
  365.   change special resource shortcuts (#$80..#$85) to their appropriate class names}
  366. Const
  367.   PreDefClasses: Array[#$80..#$85] Of pChar =
  368.     ('Button','Edit','Static','ListBox','ScrollBar','ComboBox');
  369. Begin
  370.   MangleChildClass(aChildClass);
  371.   With aChildClass Do
  372.     Case szClass[0] Of
  373.       #$80..#$85: StrCopy(szClass,PreDefClasses[szClass[0]])
  374.     End
  375. End;
  376.  
  377. Procedure tDialogWindow.MangleChildClass (Var aChildClass: tChildClass);
  378. Begin With aChildClass Do Begin
  379.   If DlgStyle And ForceBor<>0 Then Begin
  380.     If szClass[0]=#$80 Then
  381.       Case dwStyle And $F Of
  382.         bs_CheckBox,
  383.         bs_AutoCheckBox:        StrCopy(szClass,BorCheck);
  384.         bs_RadioButton..bs_Auto3State,
  385.         bs_AutoRadioButton:     StrCopy(szClass,BorRadio);
  386.         bs_GroupBox:            StrCopy(szClass,BorShade);
  387.       End
  388.   End Else
  389.   If DlgStyle And ForceStd<>0 Then Begin
  390.     If      (StrIComp(szClass,BorCheck)=0)
  391.     Or      (StrIComp(szClass,BorRadio)=0)
  392.     Or      (StrIComp(szClass,BorButton)=0) Then szClass[0]:= #$80
  393.     Else If (StrIComp(szClass,BorShade)=0)  Then
  394.       Case dwStyle And $F Of
  395.         bss_Group: Begin szClass[0]:= #$80; dwStyle:= (dwStyle And $FFFF0FF0) Or bs_GroupBox End;
  396.         bss_Hdip,
  397.         bss_Hbump,
  398.         bss_Vdip,
  399.         bss_Vbump: Begin szClass[0]:= #$82; dwStyle:= (dwStyle And $FFFFFFF0) Or ss_BlackRect End;
  400.       End
  401.   End
  402. End End;
  403.  
  404. Function tDialogWindow.CreateDialogChild ({Bp7.01: Const} Var aChildClass: tChildClass): hWnd;
  405. Var
  406.   aCtl: hWnd;
  407.   lpDlgItemInfo: Pointer;
  408.   Inst: tHandle;
  409. Begin
  410.   With DialogAttr, aChildClass Do Begin
  411.     If CtlDataSize=0 Then
  412.       lpDlgItemInfo:= Nil
  413.     Else
  414.       lpDlgItemInfo:= @CtlData;
  415.  
  416.     Inst:= System.hInstance;
  417.     If (Attr.Style And ds_LocalEdit=0) And (StrIComp(szClass, 'Edit')=0) Then Begin
  418.       If hEditBuffer=0 Then
  419.         AllocateEditBuffer;
  420.       If hEditBuffer<>0 Then
  421.         Inst:= hEditBuffer
  422.     End;
  423.  
  424.     If StrIComp(szClass,'VBControl')=0 Then
  425.       aCtl:= dVbx.CreateControl(hWindow, wId, szTitle, dwStyle,
  426.                                 DlgToClientX(wX,wUnitsX),  DlgToClientY(wY,wUnitsY),
  427.                                 DlgToClientX(wCX,wUnitsX), DlgToClientY(wCY,wUnitsY),
  428.                                 VbInfo)
  429.     Else Begin
  430.       aCtl:= CreateWindowEx(ws_Ex_NoParentNotify, szClass, szTitle, dwStyle,
  431.                             DlgToClientX(wX,wUnitsX),  DlgToClientY(wY,wUnitsY),
  432.                             DlgToClientX(wCX,wUnitsX), DlgToClientY(wCY,wUnitsY),
  433.                             hWindow, wID, Inst,
  434.                             lpDlgItemInfo);
  435.       If aCtl<>0 Then Begin
  436.         If Inst=hEditBuffer Then
  437.           SendMessage(aCtl, em_LimitText, 0, 0);
  438.         SendMessage(aCtl, wm_SetFont, Font, 0)
  439.       End
  440.     End;
  441. {$IfDef Debug}
  442.     If (aCtl=0) Or Not IsWindow(aCtl) Then
  443.       WriteLn('err DialogWn: CreateDialogChild failed! Class= ',
  444.               StrPasEx(szClass),' Title=', StrPasEx(szTitle));
  445. {$EndIf}
  446.     CreateDialogChild:= aCtl
  447.   End
  448. End;
  449.  
  450. Function tDialogWindow.CreateDialogChildren: Boolean;
  451. Var
  452.   i: Integer;
  453.   aPtr: pChar;
  454.   anItem: tChildClass;
  455.   aCtl: hWnd;
  456. Begin
  457.   CreateDialogChildren:= False;
  458.   aPtr:= DialogAttr.DlgItems;
  459.   With DialogAttr, anItem Do
  460.   For i:= 1 To DialogAttr.ItemCount Do Begin
  461.     {-copy fixed header and first byte of szClass}
  462.     Move(aPtr^,anItem,15); Inc(Word(aPtr),15);
  463.     Case szClass[0] Of
  464.       #$80..#$85: szClass[1]:= #0; {be safe}
  465.     Else
  466.       StrCopy(szClass+1, aPtr);       {copy rest of classname}
  467.       Inc(Word(aPtr),StrLen(aPtr)+1)
  468.     End;
  469.     If aPtr^=#255 Then Begin {fiddle with Caption as a number}
  470.       Str(pWord(aPtr+1)^, szTitle); {convert to '#xxx' form}
  471.       Move(szTitle[0], szTitle[1], StrLen(szTitle)+1);
  472.       szTitle[0]:= '#';
  473.       Inc(Word(aPtr), SizeOf(Byte)+SizeOf(Word))
  474.     End Else Begin
  475.       StrCopy(szTitle,aPtr);
  476.       Inc(Word(aPtr),StrLen(aPtr)+1)
  477.     End;
  478.     Move(aPtr^,CtlDataSize,Byte(aPtr^)+1);
  479.     Inc(Word(aPtr),CtlDataSize+1);
  480.     {-give descendants a chance to change child class}
  481.     GetChildClass(anItem);
  482.     aCtl:= CreateDialogChild(anItem);
  483.     If aCtl<>0 Then Begin
  484.       If (dwStyle And ws_TabStop<>0) And (FocusChildHandle=0) Then
  485.         FocusChildHandle:= aCtl; {set focus to first tab ctl}
  486.       If  (dwStyle And bs_DefPushButton<>0)
  487.       And (SendMessage(aCtl, wm_GetDlgCode, 0, 0) And DlgC_DefPushButton<>0) Then
  488.         DefId:= wId
  489.     End
  490.   End;
  491.  
  492.   {-subclass the dialog for Ctl3D}
  493.   If DlgStyle And EnableCtl3D<>0 Then
  494.     dCtl3D.SubClassDlgEx(hWindow, Ctl3DStyle);
  495.  
  496.   If (DefId=0) And (GetDlgItem(hWindow, 1)<>0) Then
  497.     DefId:= 1;  {Windows forces the Ok button to be the default button}
  498.   If DefId<>0 Then
  499.     SendMessage(GetDlgItem(hWindow, DefId), bm_SetStyle, bs_DefPushButton, 0); {so let the buttons style reflect this}
  500.   DialogAttr.DlgItems:= Nil; {no longer valid}
  501.   CreateDialogChildren:= True
  502. End;
  503.  
  504. Procedure tDialogWindow.GetDialogInfo (aPtr: Pointer);
  505. Begin
  506.   With Attr,DialogAttr Do Begin
  507.     Style:= LongInt(aPtr^);   Inc(Word(aPtr),SizeOf(LongInt));
  508.     ItemCount:= Byte(aPtr^);  Inc(Word(aPtr),SizeOf(Byte));
  509.     If Not IsFlagSet(wb_MdiChild) Then
  510.       X:= Integer(aPtr^);     Inc(Word(aPtr),SizeOf(Integer));
  511.     Y:= Integer(aPtr^);       Inc(Word(aPtr),SizeOf(Integer));
  512.     W:= Integer(aPtr^);       Inc(Word(aPtr),SizeOf(Integer));
  513.     H:= Integer(aPtr^);       Inc(Word(aPtr),SizeOf(Integer));
  514.     If Byte(aPtr^)=255 Then Begin
  515.       MenuName:= pChar(pWord(pChar(aPtr)+1)^); {<g>}
  516.       Inc(Word(aPtr), SizeOf(Byte)+SizeOf(Word))
  517.     End Else Begin
  518.       MenuName:= StrNew(aPtr);Inc(Word(aPtr),StrLen(aPtr)+1)
  519.     End;
  520.     ClassName:= StrNew(aPtr); Inc(Word(aPtr),StrLen(aPtr)+1);
  521.     Title:= StrNew(aPtr);     Inc(Word(aPtr),StrLen(aPtr)+1);
  522.     If Style And ds_SetFont>0 Then Begin
  523.       PointSize:= Integer(aPtr^); Inc(Word(aPtr),SizeOf(Integer));
  524.       FontName:= StrNew(aPtr); Inc(Word(aPtr),StrLen(aPtr)+1)
  525.     End Else Begin
  526.       PointSize:= 0;
  527.       FontName:= Nil
  528.     End;
  529.     If Style And ds_ModalFrame>0 Then
  530.       ExStyle:= ExStyle Or ws_Ex_DlgModalFrame;
  531.     DlgItems:= aPtr
  532.   End
  533. End;
  534.  
  535. Procedure tDialogWindow.StoreDMInfo;
  536. {store information in window extra words to be dialog manager compatible}
  537. Begin
  538.   SetWindowLong(hWindow, dwl_DlgProc, GetWindowLong(hWindow, gwl_WndProc)); {CTL3D compatible}
  539.   SetWindowWord(hWindow, dww_wUnitsX, DialogAttr.wUnitsX); {satisfy MapDialogRect}
  540.   SetWindowWord(hWindow, dww_wUnitsY, DialogAttr.wUnitsY); {satisfy MapDialogRect}
  541. End;
  542.  
  543. Procedure tDialogWindow.UpdateDialog;
  544. {-update and resize dialog window according to its style}
  545. Var
  546.   TheMDIClient: pMdiClient;
  547.   aRect: tRect;
  548. Begin With Attr, DialogAttr Do Begin
  549.   {-update style bits for MDI}
  550.   If isFlagSet(wb_MdiChild) Then Begin
  551.     TheMDIClient:= Parent^.GetClient;
  552.     {-check if the Client window has the MdiS_AllChildStyles bit set}
  553.     If (TheMDIClient=Nil)
  554.     Or (GetWindowLong(TheMDIClient^.hWindow, gwl_Style) And MdiS_AllChildStyles=0) Then
  555.       Style:= ws_MdiChild
  556.     Else
  557.       Style:= Style And ws_MdiAllowed Or ws_Child {reject disallowed styles}
  558.   End Else
  559.     If Style And (ws_PopUp+ws_ThickFrame)=ws_PopUp+ws_ThickFrame Then
  560.       ExStyle:= ExStyle And Not ws_Ex_DlgModalFrame; {correct Windows bug}
  561.   {-reject invisible modal window}
  562.   If Assigned(ModalCode) Then
  563.     Attr.Style:= Attr.Style Or ws_Visible;
  564.  
  565.   {-resize the window according to its style and size}
  566.   SetRect(aRect, 0, 0, DlgToClientX(w, wUnitsX), DlgToClientY(h, wUnitsY));
  567.   AdjustWindowRectEx(aRect, Style, Menu<>0, ExStyle);
  568.   w:= aRect.right-aRect.left;
  569.   h:= aRect.bottom-aRect.top;
  570.   ResW:= w;
  571.   ResH:= h
  572. End End;
  573.  
  574. Procedure tDialogWindow.MangleClass;
  575. Var
  576.   szClass: Array[0..63] Of Char;
  577.   ClassIsBorDlg: Boolean;
  578. Begin
  579.   {-if we can't find Ctl3D, disable it's usage}
  580.   If (DlgStyle And EnableCtl3D<>0) And Not dCtl3D.LibLink Then
  581.     DlgStyle:= DlgStyle And Not EnableCtl3D;
  582.   ClassIsBorDlg:= Assigned(DialogAttr.ClassName) And
  583.                   (StrLIComp(DialogAttr.ClassName, BorDialog, Length(BorDialog))=0);
  584.   If ClassIsBorDlg And (StrLIComp(DialogAttr.ClassName, BorDialogGray, Length(BorDialogGray))=0) Then
  585.     DlgStyle:= DlgStyle Or GrayBorDlg;
  586.  
  587.   {-load BWCC if the dialog needs to be a BorDlg}
  588.   If ClassIsBorDlg Or (DlgStyle And ForceBor<>0) Then
  589.     If Not dBWCC.LibLink Then {force std dialogs if BWCC can not be loaded}
  590.       DlgStyle:= DlgStyle Or ForceStd And Not ForceBor;
  591.   If DlgStyle And (ForceStd Or ForceBor)<>0 Then With DialogAttr Do Begin
  592.     If DlgStyle And ForceBor<>0 Then
  593.       StrCopy(szClass, BorDialog)
  594.     Else
  595.       szClass[0]:= #0;
  596.     If ClassIsBorDlg Then
  597.       StrCat(szClass, ClassName+Length(BorDialog))
  598.     Else
  599.       StrCat(szClass, ClassName);
  600.  
  601.     StrDispose(ClassName);
  602.     ClassName:= StrNew(szClass)
  603.   End;
  604.   IsBorDlg:= Assigned(DialogAttr.ClassName) And (StrLIComp(DialogAttr.ClassName, BorDialog, Length(BorDialog))=0)
  605. End;
  606.  
  607. Procedure tDialogWindow.CreateDialogFont;
  608. {-create the dialog font and calculate dialog units based on font}
  609. Const
  610.   aWidthString = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
  611. Var
  612.   aDC: hDC;
  613.   anOldFont: hFont;
  614.   aLogFont: tLogFont;
  615.   aTextMetric: tTextMetric;
  616. Begin With DialogAttr Do Begin
  617.   aDC:= GetDC(0);
  618.   If FontName=Nil Then
  619.     Font:= GetStockObject(System_Font)
  620.   Else Begin
  621.     FillChar(aLogFont,SizeOf(aLogFont),0);
  622.     With aLogFont Do Begin
  623.       StrCopy(lfFaceName,FontName);
  624.       lfHeight:= -MulDiv(DialogAttr.PointSize,GetDeviceCaps(aDC, LogPixelsY),72);
  625.       lfWeight:= FontWeight
  626.     End;
  627.     Font:= CreateFontIndirect(aLogFont)
  628.   End;
  629.   anOldFont:= SelectObject(aDC, Font);
  630.   GetTextMetrics(aDC, aTextMetric);
  631.   {-use the Microsoft recommended method to retrieve average width}
  632.   wUnitsX:= (Word(GetTextExtent(aDC, aWidthString, Length(aWidthString)))
  633.              Div (Length(aWidthString) Div 2) + 1) Div 2;
  634.   wUnitsY:= aTextMetric.tmHeight;
  635.   SelectObject(aDC, anOldFont);
  636.   ReleaseDC(0, aDC)
  637. End End;
  638.  
  639. Function tDialogWindow.RunModal: Integer;
  640. Var
  641.   aMsg: tMsg;
  642.   ReturnCode: Integer;
  643.   IdleParent: tHandle;
  644. Begin
  645.   ReturnCode:= 0;
  646.   ModalCode:= @ReturnCode;  {Trick OWL}
  647.   SetFlags(wb_MDIChild, False);
  648.   Create;
  649.  
  650.   If Status<>0 Then Begin
  651.     RunModal:= Status;
  652.     Exit
  653.   End;
  654.  
  655.   If Attr.Style And ds_SysModal>0 Then
  656.     SetSysModalWindow(hWindow); {support SysModal dialogs as well}
  657.   If Attr.Style And ds_NoIdleMsg>0 Then
  658.     IdleParent:= 0
  659.   Else
  660.     IdleParent:= GetParent(hWindow);
  661.   Repeat
  662.     If PeekMessage(aMsg, 0, 0, 0, pm_Remove) Then Begin
  663.       If IdleParent<>0 Then
  664.         SendMessage(IdleParent, wm_EnterIdle, MsgF_DialogBox, hWindow);
  665.       If Not Application^.ProcessDlgMsg(aMsg) Then Begin
  666.         TranslateMessage(aMsg);
  667.         DispatchMessage(aMsg)
  668.       End
  669.     End
  670.   Until ReturnCode<>0; {until window is no longer modal}
  671.   Free;
  672.   RunModal:= ReturnCode
  673. End;
  674.  
  675. Function tDialogWindow.IsModal: Boolean;
  676. Begin
  677.   IsModal:= Assigned(ModalCode)
  678. End;
  679.  
  680. Procedure tDialogWindow.EndDlg (aRetValue: Integer);
  681. Begin
  682.   If Assigned(ModalCode) Then {set return code if it's a modal window}
  683.     ModalCode^:= aRetValue
  684.   Else
  685.     CloseWindow
  686. End;
  687.  
  688. Function tDialogWindow.GetItemHandle (DlgItemID: Integer): hWnd;
  689. Begin
  690.   GetItemHandle:= GetDlgItem(hWindow, DlgItemID)
  691. End;
  692.  
  693. Function tDialogWindow.SendDlgItemMsg (DlgItemID: Integer; aMsg, wParam: Word; lParam: LongInt): LongInt;
  694. Begin
  695.   SendDlgItemMsg:= SendDlgItemMessage(hWindow, DlgItemID, AMsg, WParam, LParam)
  696. End;
  697.  
  698. Procedure tDialogWindow.Ok (Var Msg: tMessage);
  699. Begin
  700.   If Not Assigned(ModalCode) Then
  701.     CloseWindow
  702.   Else
  703.     If CanClose Then Begin
  704.       TransferData(tf_GetData);
  705.       EndDlg(id_Ok)
  706.     End
  707. End;
  708.  
  709. Procedure tDialogWindow.Cancel (Var Msg: tMessage);
  710. Begin
  711.   EndDlg(id_Cancel)
  712. End;
  713.  
  714. Procedure tDialogWindow.wmClose (Var Msg:  tMessage);
  715. Begin
  716.   EndDlg(id_Cancel)
  717. End;
  718.  
  719. Procedure tDialogWindow.wmQueryEndSession (Var Msg: tMessage);
  720. Begin
  721.   If Assigned(ModalCode) Then
  722.     If @Self=Application^.MainWindow Then
  723.       Msg.Result:= Integer(Not Application^.CanClose)
  724.     Else
  725.       Msg.Result:= Integer(Not CanClose)
  726.   Else
  727.     Inherited wmQueryEndSession(Msg)
  728. End;
  729.  
  730. Procedure tDialogWindow.wmSize (Var Msg: tMessage);
  731. Begin
  732.   Inherited wmSize(Msg);
  733.   If Assigned(Scroller) Then With Scroller^ Do Begin
  734.     AutoOrg:= Msg.wParam<>sizeIconic;
  735.     If AutoOrg Then Begin
  736.       With DialogAttr, Attr Do
  737.         SetRange(ResW-W, ResH-H);
  738.       ScrollTo(0, 0);
  739.       XLine:= XPage Div 4;
  740.       YLine:= YPage Div 4;
  741.       InvalidateRect(hWindow, Nil, True)
  742.     End
  743.   End
  744. End;
  745.  
  746. Procedure tDialogWindow.wmLButtonDown (Var Msg: tMessage);
  747. Begin
  748.   HideComboListBox;
  749.   Inherited wmLButtonDown(Msg)
  750. End;
  751.  
  752. Procedure tDialogWindow.wmNcLButtonDown (Var Msg: tMessage);
  753. Begin
  754.   HideComboListBox;
  755.   {$IfDef Custom} Inherited wmNcLButtonDown(Msg) {$Else} DefWndProc(Msg) {$EndIf}
  756. End;
  757.  
  758. Procedure tDialogWindow.wmEnterMenuLoop (Var Msg: tMessage);
  759. Begin
  760.   HideComboListBox;
  761.   DefWndProc(Msg)
  762. End;
  763.  
  764. Procedure tDialogWindow.wmActivate (Var Msg: tMessage);
  765. Begin
  766.   Inherited wmActivate(Msg);
  767.   If Msg.wParam<>0 Then
  768.     InvalidateRect(hWindow, Nil, True);
  769.  
  770.   {-this fixes an OWL bug when the last MDI child is closed}
  771.   If (Msg.wParam=0) And (Application^.kbHandlerWnd=@Self) Then
  772.     Application^.SetKBHandler(Nil)
  773. End;
  774.  
  775. Procedure tDialogWindow.HideComboListBox;
  776. Begin
  777.   SendMessage(FocusChildHandle, cb_ShowDropDown, 0, 0);
  778.   SendMessage(GetParent(FocusChildHandle), cb_ShowDropDown, 0, 0);
  779. End;
  780.  
  781. Procedure tDialogWindow.wmNextDlgCtl (Var Msg: tMessage);
  782. Var
  783.   OldFocus, NewFocus: hWnd;
  784. Begin
  785.   OldFocus:= FocusChildHandle;
  786.   If Msg.lParamLo=0 Then Begin
  787.     If OldFocus=0 Then Begin
  788.       {-set focus to the first tab item}
  789.       NewFocus:= 0;
  790.       OldFocus:= hWindow
  791.     End Else
  792.       If IsChild(hWindow, OldFocus) Then
  793.         NewFocus:= GetNextDlgTabItem(hWindow, OldFocus, WordBool(Msg.wParam))
  794.       Else
  795.         Exit {ignore message if current focus is not a dialog ctl}
  796.   End Else Begin
  797.     If OldFocus=0 Then
  798.       OldFocus:= hWindow;
  799.     NewFocus:= Msg.wParam
  800.   End;
  801.   FocusChildHandle:= NewFocus;
  802.   FocusChild;
  803.   Msg.Result:= 0
  804. End;
  805.  
  806. Procedure tDialogWindow.dmGetDefId (Var Msg: tMessage);
  807. Begin
  808.   If DefId=0 Then
  809.     Msg.Result:= 0
  810.   Else Begin
  811.     Msg.ResultLo:= DefId;
  812.     Msg.ResultHi:= dc_HasDefId
  813.   End
  814. End;
  815.  
  816. Procedure tDialogWindow.wmGetFont (Var Msg: tMessage);
  817. Begin
  818.   Msg.Result:= DialogAttr.Font
  819. End;
  820.  
  821. Procedure tDialogWindow.wmSetFocus (Var Msg: tMessage);
  822. Begin
  823.   If IsFlagSet(wb_KBHandler) And Not IsIconic(hWindow) Then Begin
  824.     Application^.SetKBHandler(@Self);
  825.     FocusChild;
  826.   End Else
  827.     Application^.SetKBHandler(Nil);
  828.   Msg.Result:= 0
  829. End;
  830.  
  831. Procedure tDialogWindow.wmCtlColor (Var Msg: tMessage);
  832. Begin
  833.   If DlgStyle And EnableCtl3D<>0 Then With Msg Do Begin
  834.     Result:= dCtl3D.CtlColorEx(Message, wParam, lParam);
  835.     If Result<>0 Then
  836.       Exit
  837.   End;
  838.   DefWndProc(Msg)
  839. End;
  840.  
  841. Procedure tDialogWindow.wmEraseBkGnd (Var Msg: tMessage);
  842. Var
  843.   aBrush,
  844.   OldBrush: hBrush;
  845.   aRect: tRect;
  846.   aPoint: tPoint;
  847. Begin
  848.   aBrush:= 0;
  849.   If Not IsBorDlg And (DlgStyle And EnableCtl3D<>0) Then
  850.     With Msg Do
  851.       aBrush:= dCtl3D.CtlColorEx(CtlColor_Dlg, wParam, MakeLong(0, CtlColor_Dlg));
  852.   If DlgStyle And (ForceGrayBk Or GrayBorDlg)<>0 Then
  853.     aBrush:= GetStockObject(LtGray_Brush);
  854.   If (aBrush=0) And IsBorDlg Then
  855.     aBrush:= dBWCC.GetPattern;
  856.   If aBrush<>0 Then Begin
  857.     GetClientRect(hWindow, aRect);
  858.     aPoint.x:= aRect.left; aPoint.y:= aRect.top;
  859.     ClientToScreen(Msg.wParam, aPoint);
  860.     UnrealizeObject(aBrush);
  861.     SetBrushOrg(Msg.wParam, (aPoint.x+1) Mod 7, aPoint.y Mod 7);
  862.     OldBrush:= SelectObject(Msg.wParam, aBrush);
  863.     With aRect Do PatBlt(Msg.wParam, left, top, right-left, bottom-top, PatCopy);
  864.     SelectObject(Msg.wParam, OldBrush);
  865.     Msg.Result:= 1
  866.   End Else
  867.     DefWndProc(Msg)
  868. End;
  869.  
  870. Procedure tDialogWindow.wmTrackFocus (Var Msg: tMessage);
  871. Var
  872.   aRect,
  873.   ClientRect: tRect;
  874.   dX, dY: Integer;
  875. Begin
  876.   FocusChildHandle:= Msg.wParam;
  877.   If Not IsIconic(hWindow) And Assigned(Scroller) And Scroller^.AutoMode Then Begin
  878.     GetWindowRect(FocusChildHandle, aRect);
  879.     GetClientRect(hWindow, ClientRect);
  880.     MapWindowPoints(0, hWindow, aRect, 2); {Screen->hWindow}
  881.     With aRect, Scroller^ Do {test if control is outside the client area}
  882.       If (left<0) Or (right>ClientRect.right)
  883.       Or (top<0)  Or (bottom>ClientRect.bottom) Then Begin
  884.         {-try to center the control in the client area}
  885.         dX:= (ClientRect.right-(right-left)) Div 2; If dX<0 Then dX:= 0;
  886.         dY:= (ClientRect.bottom-(bottom-top)) Div 2; If dY<0 Then dY:= 0;
  887.         ScrollTo((left-dX+XPos*XUnit) Div XUnit, (top-dY+YPos*YUnit) Div YUnit)
  888.       End
  889.   End
  890. End;
  891.  
  892. Procedure tDialogWindow.wmVbxFireEvent (Var Msg: tMessage);
  893. Begin
  894.   If Not EventPerform(@Self, pVbxEvent(Msg.lParam)^, id_First+pVbxEvent(Msg.lParam)^.Id) Then
  895.     DefaultEventProc(pVbxEvent(Msg.lParam)^);
  896.   Msg.Result:= 0
  897. End;
  898.  
  899. Procedure tDialogWindow.DefaultEventProc (Var Event: tVbxEvent);
  900. Begin
  901.   With Event Do If GetObjectPtr(Window)<>Nil Then {route to object}
  902.     SendMessage(Window, wm_VbxFireEvent, 0, LongInt(@Event))
  903. End;
  904.  
  905. Function ExecDialogWindow (aDialogWindow: pDialogWindow): Integer;
  906. Var
  907.   ExecReturn: Integer;
  908. Begin
  909.   ExecDialogWindow:= id_Cancel;
  910.   If Application^.ValidWindow(aDialogWindow)<>Nil Then Begin
  911.     ExecReturn:= aDialogWindow^.RunModal;
  912.     If ExecReturn<0 Then
  913.       Application^.Error(ExecReturn)
  914.     Else
  915.       ExecDialogWindow:= ExecReturn
  916.   End
  917. End;
  918.  
  919. Function tAdvApplication.ProcessDlgMsg (Var Message: tMsg): Boolean;
  920. Var
  921.   hKbdWnd,
  922.   hFocus: tHandle;
  923. Begin
  924.   ProcessDlgMsg:= False;
  925.  
  926.   If KBHandlerWnd=Nil Then Exit;
  927.   hKbdWnd:= KBHandlerWnd^.hWindow;
  928.   If hKbdWnd=0 Then Exit;
  929.  
  930.   {If (Message.Message=wm_KeyDown) And (Message.wParam=vk_Return) Then Begin
  931.     hFocus:= GetFocus;
  932.     If IsChild(hKbdWnd, hFocus)
  933.     And (SendMessage(hFocus, wm_GetDlgCode, 0, 0) And DlgC_HasSetSel<>0) Then
  934.       Message.wParam:= vk_Tab;
  935.   End;}
  936.  
  937.   If Not IsDialogMessage(hKbdWnd, Message) Then Exit;
  938.  
  939.   ProcessDlgMsg:= True;
  940.   If IsWindow(hKbdWnd) And Not IsIconic(hKbdWnd) Then Begin
  941.     hFocus:= GetFocus;
  942.  
  943.     If IsChild(hKbdWnd, hFocus)
  944.     And (pWindow(KBHandlerWnd)^.FocusChildHandle<>hFocus) Then
  945.       SendMessage(hKbdWnd, wm_TrackFocus, hFocus, 0)
  946.   End
  947. End;
  948.  
  949. Function tAdvApplication.ProcessAppMsg (Var Message: tMsg): Boolean;
  950. Const
  951.   MdiTest: (NotTested, IsMdi, IsNotMdi) = NotTested;
  952. Begin
  953.   If (MdiTest=NotTested) And Assigned(MainWindow) Then
  954.     If MainWindow^.GetClient=Nil Then
  955.       MdiTest:= IsNotMdi
  956.     Else
  957.       MdiTest:= IsMdi;
  958.   If MdiTest=IsMdi Then
  959.     ProcessAppMsg:= ProcessMDIAccels(Message)
  960.                  Or ProcessAccels(Message)
  961.                  Or ProcessDlgMsg(Message)
  962.   Else
  963.     ProcessAppMsg:= ProcessDlgMsg(Message)
  964.                  Or ProcessMDIAccels(Message)
  965.                  Or ProcessAccels(Message)
  966. End;
  967.  
  968. Procedure tAdvMdiWindow.wmActivate (Var Msg: tMessage);
  969. Var
  970.   TopWnd: hWnd;
  971. Begin
  972.   Inherited wmActivate(Msg);
  973.   If (Msg.wParam<>0) And Assigned(ClientWnd) Then Begin
  974.     TopWnd:= LoWord(SendMessage(ClientWnd^.hWindow, wm_MdiGetActive, 0, 0));
  975.     If TopWnd<>0 Then
  976.       SendMessage(TopWnd, wm_Activate, wa_Active, 0)
  977.   End
  978. End;
  979.  
  980. End.
  981.